package com.randb.easyhttp.request;

import com.google.gson.reflect.TypeToken;
import com.randb.easyhttp.cache.model.CacheResult;
import com.randb.easyhttp.callback.Callback;
import com.randb.easyhttp.callback.CallbackProxy;
import com.randb.easyhttp.func.ApiResultFunc;
import com.randb.easyhttp.func.CacheResultFunc;
import com.randb.easyhttp.func.RetryExceptionFunc;
import com.randb.easyhttp.model.ApiResult;
import com.randb.easyhttp.subscriber.CallbackSubscriber;
import com.randb.easyhttp.utils.RxUtils;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.disposables.Disposable;
import okhttp3.ResponseBody;

/**
 * User: RandBII
 * Date: 2020/5/29
 * Description:
 */

@SuppressWarnings("unchecekd")
public class DeleteRequest extends BaseBodyRequest<DeleteRequest> {
    public DeleteRequest(String url) {
        super(url);
    }


    public <T> Disposable execute(Callback<T> callback) {
        return execute(new CallbackProxy<ApiResult<T>, T>(callback) {
        });
    }

    private <T> Disposable execute(CallbackProxy<ApiResult<T>, T> callbackProxy) {
        Observable<CacheResult<T>> observable = build().toObservable(generateRequest(), callbackProxy);
        if (CacheResult.class != callbackProxy.getCallback().getRawType()) {
            return observable.compose(new ObservableTransformer<CacheResult<T>, T>() {
                @Override
                public ObservableSource<T> apply(Observable<CacheResult<T>> upstream) {
                    return upstream.map(new CacheResultFunc<T>());
                }
            }).subscribeWith(new CallbackSubscriber<T>(context, callbackProxy.getCallback()));
        } else {
            return observable
                    .subscribeWith(new CallbackSubscriber<CacheResult<T>>(context, callbackProxy.getCallback()));
        }
    }


    private <T> Observable<CacheResult<T>> toObservable(Observable<ResponseBody> observable,
                                                        CallbackProxy<ApiResult<T>, T> callbackProxy) {
        return observable.map(new ApiResultFunc(proxy != null ? callbackProxy.getType() : new TypeToken<ResponseBody>() {
        }.getType()))
                .compose(isSyncRequest ? RxUtils._main() : RxUtils._io_main())
                .compose(rxCache.transformer(cacheMode, callbackProxy.getCallback().getType()))
                .retryWhen(new RetryExceptionFunc(retryCount, retryDelay, retryIncreaseDelay));
    }



}
